/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tonyodev.fetchapp.fetch2;

import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.app.Context;

import com.tonyodev.fetch2.Download;
import com.tonyodev.fetch2.Request;
import com.tonyodev.fetch2.Status;
import com.tonyodev.fetch2.database.DownloadDatabase;
import com.tonyodev.fetch2.database.DownloadInfo;
import com.tonyodev.fetch2.database.FetchDatabaseManager;
import com.tonyodev.fetch2.database.FetchDatabaseManagerImpl;
import com.tonyodev.fetch2.database.FetchDatabaseManagerWrapper;
import com.tonyodev.fetch2.database.migration.Migration;
import com.tonyodev.fetch2.fetch.LiveSettings;
import com.tonyodev.fetch2.provider.DownloadProvider;
import com.tonyodev.fetch2.util.TypeConverterExtensions;
import com.tonyodev.fetch2core.DefaultStorageResolver;
import com.tonyodev.fetch2core.FetchCoreUtils;
import com.tonyodev.fetch2core.FetchLogger;

import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;


/**
 * @since 2021-06-11
 */
public class DownloadProviderInstrumentedTest extends TestCase {

    private FetchDatabaseManager fetchDatabaseManager;
    Context appContext ;
    private DownloadProvider downloadProvider;

    public void setUp() throws Exception {
        super.setUp();
        appContext = AbilityDelegatorRegistry.getAbilityDelegator().getAppContext();
        assertEquals("com.tonyodev.fetchapp", appContext.getBundleName());
        final String namespace = "fetch2DatabaseTest";
        final List<Migration> migrations = DownloadDatabase.getMigrations();
        FetchLogger fetchLogger = new FetchLogger(true, namespace);
        final LiveSettings liveSettings = new LiveSettings(namespace);
        DefaultStorageResolver defaultStorageResolver = new DefaultStorageResolver(appContext, FetchCoreUtils.getFileTempDir(appContext));
        System.out.println(appContext.getFilesDir().getAbsolutePath());
        fetchDatabaseManager = new FetchDatabaseManagerImpl(appContext, namespace, fetchLogger, migrations, liveSettings,
            false, defaultStorageResolver);
        final FetchDatabaseManagerWrapper databaseManagerWrapper = new FetchDatabaseManagerWrapper(fetchDatabaseManager);
        downloadProvider = new DownloadProvider(databaseManagerWrapper);
    }

    public void tearDown() throws Exception {
        fetchDatabaseManager.close();
        assertTrue(fetchDatabaseManager.isClosed());
    }


    public void testGetId() throws Exception {
        fetchDatabaseManager.deleteAll();
        final Request request = getTestRequest();
        final DownloadInfo downloadInfo = TypeConverterExtensions.toDownloadInfo(request, new DownloadInfo());
        fetchDatabaseManager.insert(downloadInfo);
        final Download query = downloadProvider.getDownload(downloadInfo.getId());
        assertNotNull(query);
        assertEquals(downloadInfo.getId(), query.getId());
    }

    public void testGetIds() throws Exception {
        fetchDatabaseManager.deleteAll();
        final String url = "http://www.example.com/test.txt";
        final String dir = appContext.getFilesDir() + "/testFolder/";
        final List<Request> requestList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            final String file = dir + "test" + i + ".txt";
            final Request request = new Request(url, file);
            requestList.add(request);
        }
        final List<DownloadInfo> downloadInfoList = new ArrayList<>();
        for (Request request : requestList) {
            final DownloadInfo downloadInfo = TypeConverterExtensions.toDownloadInfo(request, new DownloadInfo());
            downloadInfoList.add(downloadInfo);
        }
        fetchDatabaseManager.insert(downloadInfoList);
        final List<Integer> ids = new ArrayList<>();
        for (DownloadInfo downloadInfo : downloadInfoList) {
            ids.add(downloadInfo.getId());
        }
        final @NotNull List<DownloadInfo> queryList = downloadProvider.getDownloads(ids);
        assertNotNull(queryList);
        assertEquals(downloadInfoList.size(), queryList.size());
        for (Download download : queryList) {
            assertNotNull(download);
            assertTrue(ids.contains(download.getId()));
        }
    }

    public void testGetStatus() throws Exception {
        fetchDatabaseManager.deleteAll();
        final String url = "http://www.example.com/test.txt";
        final String dir = appContext.getFilesDir() + "/testFolder/";
        final List<Request> requestList = new ArrayList<>();
        final Status status = Status.QUEUED;
        for (int i = 0; i < 10; i++) {
            final String file = dir + "test" + i + ".txt";
            final Request request = new Request(url, file);
            requestList.add(request);
        }
        final List<DownloadInfo> downloadInfoList = new ArrayList<>();
        for (Request request : requestList) {
            final DownloadInfo downloadInfo = TypeConverterExtensions.toDownloadInfo(request, new DownloadInfo());
            downloadInfoList.add(downloadInfo);
        }
        for (DownloadInfo downloadInfo : downloadInfoList) {
            downloadInfo.setStatus(status);
        }
        fetchDatabaseManager.insert(downloadInfoList);
        final List<? extends Download> queryList = downloadProvider.getByStatus(status);
        assertNotNull(queryList);
        assertEquals(downloadInfoList.size(), queryList.size());
        for (Download download : queryList) {
            assertEquals(status, download.getStatus());
        }
    }



    public void testGetGroup() throws Exception {
        fetchDatabaseManager.deleteAll();
        final String url = "http://www.example.com/test.txt";
        final String dir = appContext.getFilesDir() + "/testFolder/";
        final List<Request> requestList = new ArrayList<>();
        final int group = 10;
        for (int i = 0; i < 10; i++) {
            final String file = dir + "test" + i + ".txt";
            final Request request = new Request(url, file);
            requestList.add(request);
        }
        final List<DownloadInfo> downloadInfoList = new ArrayList<>();
        for (Request request : requestList) {
            final DownloadInfo downloadInfo = TypeConverterExtensions.toDownloadInfo(request, new DownloadInfo());
            downloadInfoList.add(downloadInfo);
        }
        for (DownloadInfo downloadInfo : downloadInfoList) {
            downloadInfo.setGroup(group);
        }
        fetchDatabaseManager.insert(downloadInfoList);
        final @NotNull List<DownloadInfo> queryList = downloadProvider.getByGroup(group);
        assertNotNull(queryList);
        assertEquals(downloadInfoList.size(), queryList.size());
        for (Download download : queryList) {
            assertEquals(group, download.getGroup());
        }
    }

    public Request getTestRequest() {
        final String url = "http://www.example.com/test.txt";
        final String file = appContext.getFilesDir() + "/testFolder/test" + System.nanoTime() + ".txt";
        return new Request(url, file);
    }

}
